package scooper.cn.sc_base.log;

import android.os.AsyncTask;

import java.io.File;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.List;

import scooper.cn.sc_base.SCFileUtils;

/**
 * @author litingwei
 * @date 2019/5/14.
 */
public class LogProcessClient {

    private static class LogClientHelper {
        private static final LogProcessClient instance = new LogProcessClient();
    }

    private final List<LogConfig> configList = new ArrayList<>();
    private LogConfig defaultLogConfig;

    private LogProcessClient() {}

    public static LogProcessClient getInstance() {
        return LogClientHelper.instance;
    }

    public void initLog(LogConfig config) {
        synchronized (configList) {
            configList.add(config);
            Collections.sort(configList, new ConfigComparator());
            AsyncTask.execute(new DeleteOverdueLogTask(config));
        }
    }

    public synchronized LogConfig getDefaultConfig() {
        if (defaultLogConfig == null) {
            LogConfig.Builder builder = new LogConfig.Builder();
            defaultLogConfig = builder.build();
        }
        return defaultLogConfig;
    }

    public LogProcessClient setDefaultLogConfig(LogConfig defaultLogConfig) {
        this.defaultLogConfig = defaultLogConfig;
        return this;
    }

    public void checkAndDeleteOverdueLog() {
        synchronized (configList) {
            for (LogConfig config : configList) {
                AsyncTask.execute(new DeleteOverdueLogTask(config));
            }
        }
    }

    public void writeToFile(String className, String msg) {
        AsyncTask.execute(new WriteFileTask(className, msg));
    }

    private class DeleteOverdueLogTask implements Runnable {

        private LogConfig logConfig;

        public DeleteOverdueLogTask(LogConfig logConfig) {
            this.logConfig = logConfig;
        }

        @Override
        public void run() {
            try {
                if (logConfig.isDaily()) {
                    File dirFile = logConfig.getLogDirFile();
                    File[] files = dirFile.listFiles();
                    int prefixIndex = logConfig.getFileNamePrefix().length();
                    int dateFormatLength = logConfig.getDateFormat().toPattern().length();
                    SimpleDateFormat dateFormat = logConfig.getDateFormat();
                    long current = 0;
                    try {
                        current = dateFormat.parse(dateFormat.format(new Date())).getTime();
                    } catch (ParseException e) {
                        current = System.currentTimeMillis();
                    }
                    if (files != null && files.length > 0) {
                        for (File file : files) {
                            String fileName = file.getName();
                            if (fileName.startsWith(logConfig.getFileNamePrefix())) {
                                String dateStr = fileName.substring(prefixIndex + 1, prefixIndex + 1 + dateFormatLength);
                                try {
                                    Date date = logConfig.getDateFormat().parse(dateStr);
                                    long dif = (current - date.getTime()) / (24 * 60 * 60 * 1000);
                                    if (dif > logConfig.getRetentionPeriodDay()) {
                                        file.delete();
                                    }
                                } catch (ParseException e) {
                                    e.printStackTrace();
                                }
                            }
                        }
                    }

                } else {
                    File logFile = logConfig.getLogFile();
                    if (logFile != null && logFile.length() >= logConfig.getMaxSizeMeg() * 1024 * 1024) {
                        SCFileUtils.overlayContentToFile(logFile.getAbsolutePath(), "");
                    }

                }

                logConfig = null;
            } catch (Exception e) {}
        }

    }

    private class WriteFileTask implements Runnable {

        private String className;
        private String msg;

        public WriteFileTask(String className, String msg) {
            this.className = className;
            this.msg = msg;
        }

        @Override
        public void run() {
            synchronized (configList) {
                for (LogConfig config : configList) {
                    if (className.startsWith(config.getPackageName())) {
                        File logFile = config.getLogFile();
                        if (logFile != null) {
                            SCFileUtils.appendContentToFile(logFile.getAbsolutePath(), msg);
                        }
                        return;
                    }
                }
                LogConfig logConfig = getDefaultConfig();
                File logFile = logConfig.getLogFile();
                if (logFile != null) {
                    SCFileUtils.appendContentToFile(logFile.getAbsolutePath(), msg);
                }
            }
        }
    }

    private class ConfigComparator implements Comparator<LogConfig> {
        @Override
        public int compare(LogConfig o1, LogConfig o2) {
            return o2.getPackageName().compareTo(o1.getPackageName());
        }
    }

}
